 package srdb.migration.common;


 import oracle.sql.CLOB;
 import oracle.sql.ROWID;
// import oracle.sql.TIMESTAMP;
// import oracle.sql.TIMESTAMPTZ;
 import srdb.migration.MigrationToolkit;
 import srdb.migration.Utility;
 import srdb.migration.schema.metadata.Table;

 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 import java.sql.Blob;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.Statement;
 import java.text.SimpleDateFormat;
 
 public class MTKOfflineBridge extends MTKBridge
 {
   IMTKConnection srcConn = null;
   OutputStream stream = null;
 
   public MTKOfflineBridge(IMTKConnection srcConn) {
     super(srcConn, null);
     this.srcConn = srcConn;
   }
 
   public long setTableData(Table table, int batchSize, MTKConstants.DATABASE_TYPE sourceDBType, MTKConstants.DATABASE_TYPE targetDBType) throws Exception
   {
     return setTableDataInSafeMode(table, sourceDBType, targetDBType);
   }
 
   public long setTableDataInSafeMode(Table table, MTKConstants.DATABASE_TYPE sourceDBType, MTKConstants.DATABASE_TYPE targetDBType) throws Exception
   {
     long rowCount = 0L;
     OutputStream stream = null;
     Statement srcStatement = null;
     Exception ex = null;
     String lineSep = System.getProperty("line.separator");
     String dateFormat = "dd MMM yyyy HH:mm:ss.SS";
     String pgDateFormat = "DD Mon YYYY HH24:MI:SS.MS";
     SimpleDateFormat dtFmt = new SimpleDateFormat(dateFormat);
 
     String pgTsTzFormat = "YYYY-MM-DD HH24:MI:SS.MS";
     try
     {
       stream = openStream(table.getSchema(), table.getName());
       String insertStrPrefix = "INSERT INTO " + table.getTargetSchemaQualifiedName() + " VALUES (";
       srcStatement = this.srcConn.getConnection().createStatement();
       ResultSet rs = srcStatement.executeQuery(table.getSelectSQL());
       ResultSetMetaData rsmd = rs.getMetaData();
       while (rs.next()) {
         String insertStr = insertStrPrefix;
         for (int i = 1; i <= rsmd.getColumnCount(); i++) {
           Object val = rs.getObject(i);
           if (!rs.wasNull())
           {
             int columnType = rsmd.getColumnType(i);
             switch (columnType) {
             case -7:
             case -5:
             case 2:
             case 3:
             case 4:
             case 5:
             case 6:
             case 8:
             case 16:
               insertStr = insertStr + val.toString();
               break;
             case 2004:
               Blob b = (Blob)val;
               insertStr = insertStr + "DECODE(" + quoteIdentifier(Utility.bytesToHexString(b)) + ", 'hex')";
               break;
             case -101:
             case 91:
             case 93:
               if (sourceDBType != MTKConstants.DATABASE_TYPE.ORACLE) break;
//               if ((val instanceof TIMESTAMP)) {
//                 val = ((TIMESTAMP)val).timestampValue();
//                 String dt = dtFmt.format(val);
//                 insertStr = insertStr + "to_timestamp('" + dt + "','" + pgDateFormat + "')"; } else {
//                 if (!(val instanceof TIMESTAMPTZ)) break;
//                 insertStr = insertStr + "to_timestamp('" + rs.getTimestamp(i).toString() + "','" + pgTsTzFormat + "')"; } break;
             case 1111:
               if (sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE) {
                 if ((val instanceof ROWID))
                   insertStr = insertStr + quoteIdentifier(rs.getString(i));
                 else
                   insertStr = insertStr + quoteIdentifier(val.toString());
               }
               else {
                 insertStr = insertStr + quoteIdentifier(val.toString());
               }
               break;
             case 2005:
               if (sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE) {
                 if ((val instanceof CLOB))
                   insertStr = insertStr + quoteIdentifier(rs.getString(i));
                 else
                   insertStr = insertStr + quoteIdentifier(val.toString());
               }
               else {
                 insertStr = insertStr + quoteIdentifier(val.toString());
               }
               break;
             default:
               insertStr = insertStr + quoteIdentifier(val.toString());
             }
 
           }
           else
           {
             insertStr = insertStr + " null ";
           }
           if (i < rsmd.getColumnCount()) {
             insertStr = insertStr + " , ";
           }
         }
         insertStr = insertStr + ");";
         stream.write(insertStr.getBytes());
         stream.write(lineSep.getBytes());
         rowCount += 1L;
       }
     } catch (Exception exp) {
       exp.printStackTrace();
       ex = exp; } finally {
       try {
         srcStatement.close(); } catch (Exception e) {
       }try { stream.close(); } catch (Exception e) {
       }
     }
     if (ex != null) {
       throw ex;
     }
     return rowCount;
   }
 
   private String quoteIdentifier(String src)
   {
     if (src == null)
       return src;
     if (src.indexOf("'") < 0) {
       return "'" + src + "'";
     }
     StringBuffer target = new StringBuffer();
     target.append("'");
     for (int i = 0; i < src.length(); i++) {
       char c = src.charAt(i);
       if (c == '\'') {
         target.append("'");
       }
       target.append(c);
     }
     target.append("'");
     return target.toString();
   }
 
   private OutputStream openStream(String schemaName, String tableName)
     throws FileNotFoundException
   {
     if (MigrationToolkit.getInstance().useSingleDataFile()) {
       return new FileOutputStream(MTKMetaData.offlineMigrationSchemaDDLFilePath + File.separator + "mtk_" + schemaName.toLowerCase() + "_data.sql", true);
     }
     return new FileOutputStream(MTKMetaData.offlineMigrationSchemaDDLFilePath + File.separator + "mtk_" + schemaName.toLowerCase() + "_" + tableName.toLowerCase() + "_data.sql");
   }
 }

/* 

 * 
 */